package com.dataextend.service;


import com.alibaba.fastjson.JSONObject;
import com.dataextend.Enum.TagCodeEnum;
import com.dataextend.entity.DistributeAnalysisRequest;
import com.dataextend.mapper.master.ClickhouseMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 *  Clickhouse 分布分析模型
 */
@Slf4j
@Service
public class ClickhouseDistributeService {
    @Autowired
    ClickhouseMapper clickhouseMapper;


    // clickhouse查询
    private List<JSONObject> distributeAnalysis(String startDate, String endDate, String eventCodes, String dimension, List<JSONObject> filterParam){
        StringBuilder permission = new StringBuilder();
        String condition = null;
        String filterParam_ = null;
        if (filterParam.size()>0){
            for (JSONObject obj : filterParam){
                String type = obj.getString("type");
                String field = obj.getString("field");
                String name = obj.getString("name");
                String tag = obj.getString("tag");
                if (type.equals("event")){
                    condition = " and (" + field + "='" + tag + "')";
                    permission.append(condition);

                } else {
                    String fieldName = "tag_" + field;
                    condition = " and (" + fieldName + "='" + tag + "')";
                    permission.append(condition);
                }
            }
            filterParam_ = permission.toString();
        } else {
            filterParam_ = "";
        }

        String group_dimension_1 = " count(case when t.num>=1 and t.num<3 then t.distinct_id end) first_num, ";
        String group_dimension_2 = " count(case when t.num>=3 and t.num<5 then t.distinct_id end) second_num, ";
        String group_dimension_3 = " count(case when t.num>=5 and t.num<10 then t.distinct_id end) third_num, ";
        String group_dimension_4 = " count(case when t.num>=10 then t.distinct_id end) forth_num ";
        String has_dimension_1 = " select distinct_id,datadate,count(*) as num ";
        String has_dimension_2 = " from ads.userprofile_analysis_model ";
        String has_dimension_3 = " where datadate>='";
        String groupby = "t." + dimension;
        String search_sql = null;
        // 没有细分维度
        if (StringUtils.isEmpty(dimension)){
            search_sql = "select " + group_dimension_1 + group_dimension_2 + group_dimension_3+ group_dimension_4 + " from ("
            + has_dimension_1 + has_dimension_2 + has_dimension_3 + startDate + "' and datadate<='" + endDate + "' and  clickevent = '"
            + eventCodes + "' " + filterParam_ + " group by distinct_id,datadate ) t ";
        } else {
            // 存在细分维度
            search_sql =  "select " + groupby + ", " + group_dimension_1 + group_dimension_2 + group_dimension_3+ group_dimension_4 + " from("
                    + " select distinct_id," + dimension + ", datadate,count(*) as num  from ads.userprofile_analysis_model where clickevent = '" +eventCodes +
                    "' and datadate>='"  + startDate + "' and datadate<='" + endDate + "' " + filterParam_ + " group by distinct_id," + dimension + ", datadate" + " ) t " + " group by " + groupby;
        }

        log.info("--->search_sql: {}" , search_sql);
        List<JSONObject> searchResult = clickhouseMapper.distributeAnalysis(search_sql);
        return searchResult;
    }


    // 所有分组的维度
    private List<String> allDimension(List<JSONObject> searchDetail, String dimension){
        List<String> dimensions = new ArrayList<>();
        for (JSONObject obj : searchDetail){
            String save = obj.getString(dimension);
            dimensions.add(save);
        }
        return dimensions.stream().distinct().collect(Collectors.toList());
    }


    // 解析查询结果,拼接成合适的数据格式
    private List<JSONObject> resolveResult(List<JSONObject> searchDetail, String dimension){
        List<JSONObject> returnResult = new ArrayList<>();

        // 没有细分维度
        if (StringUtils.isEmpty(dimension)){
            List<Long> values = new ArrayList<>();
            JSONObject detailInfo = new JSONObject(true);
            for (JSONObject obj : searchDetail){
                values.add(obj.getLongValue("first_num"));
                values.add(obj.getLongValue("second_num"));
                values.add(obj.getLongValue("third_num"));
                values.add(obj.getLongValue("forth_num"));
            }
            detailInfo.put("legend", "");
            detailInfo.put("value", values);
            detailInfo.put("total", values.stream().reduce(Long::sum).orElse(0L));
            returnResult.add(detailInfo);
        } else {
            // 存在细分维度
            List<String> allDimensions = allDimension(searchDetail, dimension);
            log.info("----------allDimensions:" + allDimensions);
            for (String group : allDimensions){
                JSONObject detailInfo = new JSONObject(true);
                List<Long> values = new ArrayList<>();
                for (JSONObject obj :searchDetail){
                    if (group.equals(obj.getString(dimension))){
                        values.add(obj.getLongValue("first_num"));
                        values.add(obj.getLongValue("second_num"));
                        values.add(obj.getLongValue("third_num"));
                        values.add(obj.getLongValue("forth_num"));

                        if (group.contains("_")){
                            detailInfo.put("legend", TagCodeEnum.getName(group));
                        } else {
                            detailInfo.put("legend", group);
                        }
                        detailInfo.put("value", values);
                        detailInfo.put("total", values.stream().reduce(Long::sum).orElse(0L));
                    }
                }
                returnResult.add(detailInfo);
            }
        }

        return returnResult;
    }


    /**
     *  请求返回函数
     */
    public JSONObject findCound(DistributeAnalysisRequest distributeAnalysisRequest){
        // 查询clickhouse
        List<JSONObject> searchDetail = distributeAnalysis(distributeAnalysisRequest.getStartDate(), distributeAnalysisRequest.getEndDate(), distributeAnalysisRequest.getEventCodes(),
                distributeAnalysisRequest.getDimension(), distributeAnalysisRequest.getFilterParameter());

        // 解析返回的结果
        List<JSONObject> detailResult = resolveResult(searchDetail, distributeAnalysisRequest.getDimension());

        JSONObject returnResult = new JSONObject(true);
        List<String> legend = new ArrayList<>();
        legend.add("[1,3)");
        legend.add("[3,5)");
        legend.add("[5,10)");
        legend.add("[10,20)");
        returnResult.put("list", detailResult);
        returnResult.put("legend", legend);

        return returnResult;
    }


}
